package org.jim.server.command.cs;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import org.jim.connector.command.CsAllocHelper;
import org.jim.core.ImChannelContext;
import org.jim.core.ImConst;
import org.jim.core.ImPacket;
import org.jim.core.ImStatus;
import org.jim.core.config.ImConfig;
import org.jim.core.exception.ImException;
import org.jim.core.helper.cs.ICsSessionHelper;
import org.jim.core.packets.pub.consts.Command;
import org.jim.core.packets.RespBody;
import org.jim.core.packets.pub.consts.ChatType;
import org.jim.core.packets.cs.chat.command.CsChatReqCmd;
import org.jim.core.packets.pub.pojo.JimChatBody;
import org.jim.core.packets.cs.session.vo.JimCsSession;
import org.jim.server.ImServerChannelContext;
import org.jim.server.JimServerAPI;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.command.CommandHandler;
import org.jim.server.config.ImServerConfig;
import org.jim.server.processor.chat.CsAsyncChatMessageProcessor;
import org.jim.server.protocol.ProtocolManager;
import org.jim.server.queue.MsgQueueRunnable;
import org.jim.server.util.ChatKit;
import org.jim.server.util.CsChatKit;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Objects;

/**
 * 版本: [1.0]
 * 功能说明: 聊天请求cmd消息命令处理器
 *
 * @author : WChao 创建时间: 2017年9月22日 下午2:58:59
 */
@CommandHandler(cmd = Command.COMMAND_CHAT_REQ, cmdProcessorClasses = CsAsyncChatMessageProcessor.class)
public class CsChatReqHandler extends AbstractCmdHandler {
    @Autowired
    private ICsSessionHelper csSessionHelper;

    @Override
    public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException {
        ImServerChannelContext imServerChannelContext = (ImServerChannelContext) channelContext;
        if (packet.getBody() == null) {
            throw new ImException("body is null");
        }
        CsChatReqCmd chatReqBodyCmd = CsChatKit.toChatBody(packet.getBody(), channelContext);
        packet.setBody(chatReqBodyCmd.toByte());
        //聊天数据格式不正确
        if (chatReqBodyCmd == null || ChatType.forNumber(chatReqBodyCmd.getChatType()) == null) {
            ImPacket respChatPacket = ProtocolManager.Packet.dataInCorrect(channelContext);
            return respChatPacket;
        }
        //获取session,并且校验
        String sessionId = chatReqBodyCmd.getTo();
        String ctxUserId = channelContext.getUserId();
        //获取session对象
        ImServerConfig imServerConfig = ImConfig.Global.get();
        //异步调用业务处理消息接口(持久化)
        JimChatBody chatBody = new JimChatBody();
        BeanUtil.copyProperties(chatReqBodyCmd, chatBody);
        chatBody.setSessionId(sessionId);

        //临时的session
        if (sessionId != null && sessionId.indexOf(TEMP) != -1) {
            //发送异步消息
            JimCsSession csSession = CsAllocHelper.parseJWT(sessionId.substring(ImConst.TEMP.length(), sessionId.length()));
            chatBody.setCsTenantId(csSession.getCsTenantId());
            msgQueueRunnable(imServerChannelContext, chatBody);
            return null;
        } else {
            JimCsSession jimCsSession = csSessionHelper.get(sessionId);
            if (jimCsSession == null) {
                return ProtocolManager.Packet.chatFail(channelContext, ImStatus.C_FAIL.getCode(), "invalid session");
            }
            chatBody.setCsTenantId(jimCsSession.getCsTenantId());
            chatBody.setCsTenantCate(jimCsSession.getCsTenantCate());
            chatBody.setCsTenantLogo(jimCsSession.getCsTenantLogo());
            chatBody.setCsTenantName(jimCsSession.getCsTenantName());
            //根据session对象,确定发送到的用户
            String toUserId = "";
            if (ctxUserId.equals(jimCsSession.getUserId())) {
                toUserId = jimCsSession.getCsId();
                chatBody.setToName(jimCsSession.getCsNick());
                chatBody.setFormName(jimCsSession.getUserNick());
                chatBody.setOperateType(ImConst.USER_OPERATE);
            } else if (ctxUserId.equals(jimCsSession.getCsId())) {
                toUserId = jimCsSession.getUserId();
                chatBody.setToName(jimCsSession.getUserNick());
                chatBody.setFormName(jimCsSession.getCsNick());
                chatBody.setOperateType(ImConst.CS_OPERATE);
            }
            if (StrUtil.isBlank(toUserId)) {
                return ProtocolManager.Packet.chatFail(channelContext, ImStatus.C_FAIL.getCode(), "invalid user");
            }
            chatBody.setTo(toUserId);
            //发送异步消息
            msgQueueRunnable(imServerChannelContext, chatBody);
            ImPacket chatPacket = new ImPacket(Command.COMMAND_CHAT_REQ, new RespBody(Command.COMMAND_CHAT_REQ, chatBody).toByte());
            //设置同步序列号;
            chatPacket.setSynSeq(packet.getSynSeq());
            boolean isStore = ImServerConfig.ON.equals(imServerConfig.getIsStore());
            //客服聊天

            if (ChatKit.isOnline(toUserId, isStore)) {
                JimServerAPI.sendToUser(toUserId, chatPacket);
                //发送成功响应包
                return ProtocolManager.Packet.success(channelContext);
            } else {
                //用户不在线响应包
                return ProtocolManager.Packet.offline(channelContext);
            }
        }
    }

    @Override
    public Command command() {
        return Command.COMMAND_CHAT_REQ;
    }

    /**
     * 异步发送消息
     *
     * @param imServerChannelContext IM通道上下文
     * @return
     */
    private void msgQueueRunnable(ImServerChannelContext imServerChannelContext, JimChatBody chatBody) {
        MsgQueueRunnable msgQueueRunnable = (MsgQueueRunnable) imServerChannelContext.getMsgQue();
        if (Objects.isNull(msgQueueRunnable.getProtocolCmdProcessor())) {

            synchronized (MsgQueueRunnable.class) {
                msgQueueRunnable.setProtocolCmdProcessor(this.getSingleProcessor());
            }
        }
        msgQueueRunnable.addMsg(chatBody);
        msgQueueRunnable.executor.execute(msgQueueRunnable);
    }

}
